package net.esj.basic.core.view.filter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import net.esj.basic.utils.view.HtmlUtils;

import org.apache.struts2.ServletActionContext;
import org.springframework.util.StringUtils;

public class StaticPageFilter implements Filter {

	private static final String DEFAULT_PAGE_REGEX = "^[(0-9)_(0-9)]*"; //默认匹配1234_1这种格式的文件
	private static final String DEFAULT_STATIC_PAGE_POSTFIX = "html";
	private static final String DEFAULT_DYNAMIC_PAGE_POSTFIX = "htm";

	private String regex = DEFAULT_PAGE_REGEX;

	private String dynamicPagePostfix = DEFAULT_DYNAMIC_PAGE_POSTFIX;
	private String staticPagePostfix = DEFAULT_STATIC_PAGE_POSTFIX;
	
	private String contextStaticFilePath;
	
	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) arg0;
		HttpServletResponse response = (HttpServletResponse) arg1;
		
		String uri = request.getRequestURI();
		int lastPosition = uri.lastIndexOf('/');
		int postfixPosition = uri.lastIndexOf(".");
		if(postfixPosition<0){
			arg2.doFilter(request, response);
			return;
		}

		String postfix = uri.substring(postfixPosition);
		if(!Pattern.matches(staticPagePostfix,postfix)){
			arg2.doFilter(request, response);
			return;
		}
		String last = uri.substring(lastPosition, postfixPosition);
		
		if(DEFAULT_STATIC_PAGE_POSTFIX.equals(postfix)){//静态页
			StatusExposingServletResponseWrapper resp = new StatusExposingServletResponseWrapper(response);
			arg2.doFilter(request, resp);
			int status = resp.getStatus();
			if(status == HttpServletResponse.SC_NOT_FOUND){//当页面找不到时生成
				if(Pattern.matches(regex, last)){
					String dyncPage = uri.substring(0, postfixPosition)+dynamicPagePostfix;
					
					if(!contextStaticFilePath.endsWith("/")){
						contextStaticFilePath+="/";
					}
					String path = uri.substring(0,lastPosition);
					path = contextStaticFilePath + path;
					String fileAbsName =  contextStaticFilePath+uri;
					File dir = new File(path);
					if(!dir.exists()){
						dir.mkdirs();
					}
					File f = new File(fileAbsName);
					ServletContext sc = ServletActionContext.getServletContext();
					OutputStream os = HtmlUtils.readPageToStream(dyncPage, "utf-8", sc, request, response);
					FileOutputStream fos = new FileOutputStream(f);
					
					fos.write(os.toString().getBytes());
					fos.close();
					
					arg2.doFilter(request, response);//再访问一遍，不行就算了
				}
			}
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		String rg = arg0.getInitParameter("staticRegex");
		if(StringUtils.hasText(rg)){
			regex = rg;
		}
		String dp = arg0.getInitParameter("dynamicPagePostfix");
		if(StringUtils.hasText(dp)){
			dynamicPagePostfix = dp;
		}
		String sp = arg0.getInitParameter("staticPagePostfix");
		if(StringUtils.hasText(sp)){
			staticPagePostfix = sp;
		}
	}

	public static class StatusExposingServletResponseWrapper extends
			HttpServletResponseWrapper {

		private int httpStatus;

		public StatusExposingServletResponseWrapper(HttpServletResponse response) {
			super(response);
		}

		@Override
		public void sendError(int sc) throws IOException {
			httpStatus = sc;
			super.sendError(sc);
		}

		@Override
		public void sendError(int sc, String msg) throws IOException {
			httpStatus = sc;
			super.sendError(sc, msg);
		}

		@Override
		public void setStatus(int sc) {
			httpStatus = sc;
			super.setStatus(sc);
		}

		public int getStatus() {
			return httpStatus;
		}

	}
	
	public void setStaticPagePostfix(String staticPagePostfix) {
		this.staticPagePostfix = staticPagePostfix;
	}

	public static void main(String[] args){
		//System.out.println(Pattern.matches("^[(0-9)_(0-9)]*", "0435345-1212"));
//		Pattern p = Pattern.compile("(我操|我单)");
//		Matcher m = p.matcher("地方的施工方的说法广东省我操啊实打实的我单啊实打实的");
//		System.out.println(m.find());
		
		File f = new File("E://org/esd/ee");
		if(!f.exists()){
			f.mkdirs();
		}
	}
}
